<?php
class FileUpload {
	private $filePath;   //* 文件目的路径
	private $fileField; //* 默认$_FILES[$fileField],通过$_FILES环境变量获取上传文件信息
	private $originName; //源文件名
	private $tmpFileName; //临时文件名
	private $fileType; //文件类型(文件后缀)
	private $fileSize; //文件大小
	private $newFileName; //新文件名
	private $allowType = array('jpg','gif','png');
	private $maxSize = 2000000; //允许文件上传的最大长度2m
	private $isUserDefName = false; //是否采用用户自定义名
	private $userDefName; //用户定义名称
	private $isRandName = true; //是否随机重命名
	private $randName; //系统随机名称
	private $errorNum = 0; //错误号
	private $isCoverModer = true; //是否覆盖模式

	function __construct($options=array()) {
		$this->setOptions($options);//设置上传时属性列表
	}

	function uploadFile($filefield) {
		$this->setOption('errorNum',0); //设置错误位
		$this->setOption('fileField', $filefield);//设置fileField
		$this->setFiles(); //设置文件信息
		$this->checkValid();//判断合法性
		$this->checkFilePath();//检查文件路径
		$this->setNewFileName(); //设置新文件名
		if ($this->errorNum < 0) //检查是否出错
			return $this->errorNum;
		return $this->copyFile(); //上传文件
	}

	private function setOptions($options=array()) {
		foreach ($options as $key=>$val) {
			if (!in_array($key, array('filePath','fileField','originName','allowType','maxSize','isUserDefName','userDefName','isRandName','randName')))
				continue;
			$this->setOption($key, $val);
		}
	}

	private function setFiles() {
		if ($this->getFileErrorFromFILES() != 0) {
			$this->setOption('errorNum', -1);
			return $this->errorNum;
		}
			
		$this->setOption('originName', $this->getFileNameFromFILES());
		$this->setOption('tmpFileName', $this->getTmpFileNameFromFILES());
		$this->setOption('fileType', $this->getFileTypeFromFILES());
		$this->setOption('fileSize', $this->getFileSizeFromFILES());

	}


	private function setOption($key, $val) {
		$this->$key = $val;
	}

	private function setNewFileName() {
		if ($this->isRandName == false && $this->isUserDefName == false) {
			$this->setOption('newFileName', $this->originName);
		} else if ($this->isRandName == true && $this->isUserDefName == false) {
			$this->setOption('newFileName', $this->proRandName().'.'.$this->fileType);
		} else if ($this->isRandName == false && $this->isUserDefName == true) {
			$this->setOption('newFileName', $this->userDefName);
		} else {
			$this->setOption('errorNum', -4);
		}
	}

	private function checkValid() {
		$this->checkFileSize();
		$this->checkFileType();
	}

	private function checkFileType() {
		if (!in_array($this->fileType, $this->allowType))
			$this->setOption('errorNum', -2);
		return $this->errorNum;
	}

	private function checkFileSize() {
		if ($this->fileSize > $this->maxSize)
			$this->setOption('errorNum', -3);
		return $this->errorNum;
	}

	private function checkFilePath() {
		if (!file_exists($this->filePath)) {
			if ($this->isCoverModer) {
				$this->makePath();
			} else {
				$this->setOption('errorNum', -6);
			}
		}
	}

	private function proRandName() {
		$tmpStr = "abcdefghijklmnopqrstuvwxyz0123456789";
		$str = "";
		for ($i=0; $i<8; $i++) {
			$num = rand(0, strlen($tmpStr));
			$str .= $tmpStr[$num];
		}
		return $str;
	}

	private function makePath() {
		if (!@mkdir($this->filePath, 0755)) {
			$this->setOption('errorNum', -7);
		}
	}

	private function copyFile() {
		$filePath = $this->filePath;
		if ($filePath[strlen($filePath)-1] != '/') {
			$filePath .= '/';
		}
			
		$filePath .= $this->newFileName;
		if (!@move_uploaded_file($this->tmpFileName, $filePath)) {
			$this->setOption('errorNum', -5);
		}
		return $this->errorNum;
	}

	function getNewFileName(){
		return $this->newFileName;
	}

	private function getFileErrorFromFILES() {
		return $this->fileField['error'];
	}

	private function getFileTypeFromFILES() {
		$str = $this->fileField['name'];
		$aryStr = split("\.", $str);
		$ret = strtolower($aryStr[count($aryStr)-1]);
		return $ret;
	}

	private function getFileNameFromFILES() {
		return $this->fileField['name'];
	}

	private function getTmpFileNameFromFILES() {
		return $this->fileField['tmp_name'];
	}

	private function getFileSizeFromFILES() {
		return $this->fileField['size'];
	}

	public function getErrorMsg() {
		$str = "上传文件出错 : ";
		switch ($this->errorNum) {
			case -1:
				$str .= "未知错误";
				break;
			case -2:
				$str .= "未允许类型";
				break;
			case -3:
				$str .= "文件过大";
				break;
			case -4:
				$str .= "产生文件名出错";
				break;
			case -5:
				$str .= "上传失败";
				break;
			case -6:
				$str .= "目录不存在";
				break;
			case -7:
				$str .= "建立目录失败";
				break;
		}
		return $str;
	}
}
?>